package com.linkoog.devtools.mybatis.parse_log.common;

import com.google.common.base.Splitter;
import org.apache.commons.lang3.StringUtils;

import java.util.ArrayList;
import java.util.List;

/**
 * 解析mybatis的log为完整的sql语句
 */
public class MyBatisLogParser {

    public static final String SQL_PREFIX = "Preparing:";
    public static final String PARAM_PREFIX = "Parameters:";
    public static final String EXCLUDE_SQL = "Preparing: INSERT INTO";

    public static List<String> toSql(String str, boolean format) {
        try {
            return parseLog(str, format);
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("sql日志解析错误", e);
        }
    }


    private static List<String> parseLog(String logStr, boolean format) {
        List<String> sqlList = new ArrayList<>();
        if (StringUtils.isBlank(logStr)){
            return sqlList;
        }

        if (!logStr.contains(SQL_PREFIX) || !logStr.contains(PARAM_PREFIX)) {
            return sqlList;
        }


        List<String> list = Splitter.on("\n").omitEmptyStrings().splitToList(logStr);

        for (int i = 0; i < list.size(); i++) {
            String rowlog = list.get(i);
            String rawSql = StringUtils.substringAfter(rowlog, SQL_PREFIX);
            if (StringUtils.isBlank(rawSql)){
                continue;
            }

            String paramStr = null;
            if ((i + 1) < list.size()){
                String nextRowlog = list.get(i + 1);
                paramStr = StringUtils.isNotBlank(nextRowlog) ? StringUtils.substringAfter(nextRowlog, PARAM_PREFIX) : null;
            }

            String sql = rawSql;
            if (StringUtils.isNotBlank(paramStr)) {
                List<String> paramList = Splitter.on(",").omitEmptyStrings().splitToList(paramStr);
                for (String param : paramList) {
                    String pType = StringUtils.substringBetween(param, "(", ")");
                    param = param.trim().replace("(" + pType + ")", "");
                    String targetStr = null;
                    if ("String".equals(pType) || "Timestamp".equals(pType)) {
                        targetStr = "'" + param + "'";
                    } else if ("Integer".equals(pType) || "Long".equals(pType) || "Double".equals(pType) || "Float".equals(pType)) {
                        targetStr = param;
                    } else {
                        targetStr = param;
                    }
                    sql = sql.replaceFirst("\\?", targetStr);
                }
            }

            if (format) {
                sqlList.add(SqlFormatter.format(sql));
            } else {
                sqlList.add(sql);
            }

        }
        return sqlList;
    }


}
